package it.polimi.protopeer.simulation.manager;

import java.awt.BorderLayout;
import java.awt.Component;
import java.io.*;
import java.util.StringTokenizer;

import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import org.jfree.chart.*;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.*;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

/**
 * This class creates an XY chart using the data in gc.csv.
 *
 * @author Rikesh Naralloo
 */
public class ChartCreator extends ApplicationFrame {

    private static final boolean SHOW_LEGEND = true;
    private static final boolean SHOW_TOOLTIPS = true;
    private static final boolean GENERATE_URLS = false;
    private String yLabel;
    private String path;
    private final String[] LABEL={
    	"time","attempted_reconfigurations_count","successful_reconfigurations_count",
    	"reconfiguration_traffic_events","reconfiguration_traffic_size","total_overlay_traffic_events",
    	"total_overlay_traffic_size","sub_overlay_traffic_events","sub_overlay_traffic_size",
    	"pub_overlay_traffic_events","pub_overlay_traffic_size","total_incoming_traffic_events",
    	"total_incoming_traffic_size","sub_incoming_traffic_events","sub_incoming_traffic_size",
    	"pub_incoming_traffic_events","pub_outgoing_traffic_events","pub_outgoing_traffic_size"
    	
    };
    
    private final String[] ALGORITHMS={
    		"Null",
    		"SAT",
    		"OCBR"
    };
    
    public ChartCreator(String path,final String title){
    	super(title);
    	this.path=path;
//        final JFreeChart chart = plot();
//        final ChartPanel panel = new ChartPanel(chart, true, true, true, false, true);
//        panel.setPreferredSize(new java.awt.Dimension(800, 500));
        setContentPane(createTab());
    }

    public JPanel createTab(){
    	JPanel panel=new JPanel(new BorderLayout());
    	JTabbedPane tabbedPane = new JTabbedPane();
    	JFreeChart[] chart=plot();
    	for (int i = 0; i < chart.length; i++) {
    	      tabbedPane.addTab(LABEL[i+1], createPane(chart[i]));
    	    }
    	tabbedPane.setSelectedIndex(0);
        panel.add(tabbedPane, BorderLayout.CENTER);
    	return panel;
    }
    
    private JPanel createPane(JFreeChart chart) {
    	JPanel p = new JPanel();
    	final ChartPanel panel = new ChartPanel(chart, true, true, true, false, true);
    	panel.setPreferredSize(new java.awt.Dimension(800, 500));
    	p.add(panel);
		return p;
	}

	public XYDataset[] createChart(){
        FileReader fr=null;
        BufferedReader br=null;
        final XYSeries[] seriesNull;
        final XYSeries[] seriesSAT;
        final XYSeries[] seriesOCBR;
        final XYSeriesCollection[] collection = new XYSeriesCollection[18];
        for(int i=0;i<collection.length;i++)
        	collection[i]=new XYSeriesCollection();
        
        final CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain"));
        plot.setGap(10.0);
		try {
			fr = new FileReader(path+"Null_result.csv");
			if(fr!=null){
				seriesNull = new XYSeries[18];
				for(int i=0;i<seriesNull.length;i++)
					seriesNull[i]=new XYSeries("Null");
		        br  = new BufferedReader(fr);
		
		        // Get the x-axis label from the first token in the first line
		        // and the y-axis label from the last token in the first line.
		        String line = br.readLine();
		        StringTokenizer st = new StringTokenizer(line, " ");
		        String xLabel = LABEL[0];
		        int i=1;
		        br.close();
		        while(st.hasMoreTokens()){
		        	fr = new FileReader(path+"Null_result.csv");
		        	br  = new BufferedReader(fr);
		        	yLabel = LABEL[i];
		        	
			
			        String title = yLabel + " by " + xLabel;
			
			        // Get the data to plot from the remaining lines.
			        float minY = Float.MAX_VALUE;
			        float maxY = -Float.MAX_VALUE;
			        while (true) {
			            line = br.readLine();
			             
			            if (line == null) {
			            	break;
			            }
			            st = new StringTokenizer(line, " ");
			
			            // The first token is the x value.
			            String xValue = st.nextToken();
			
			            // The last token is the y value.
			            String yValue = "";
			            int j=0;
			            while (j<i){
			            	yValue = st.nextToken();
			            	j++;
			            }
			
			            float x = Float.parseFloat(xValue);
			            float y = Float.parseFloat(yValue);
			            seriesNull[i].add(x, y);
			
			            minY = Math.min(y, minY);
			            maxY = Math.max(y, maxY);
			        }
			        collection[i].addSeries(seriesNull[i]);
			        i++;
//			        XYSeriesCollection dataset = new XYSeriesCollection();
//			        dataset.addSeries(series);
//			
//			        JFreeChart chart = ChartFactory.createXYLineChart(
//			            title, xLabel, yLabel, dataset,
//			            PlotOrientation.VERTICAL,
//			            SHOW_LEGEND, SHOW_TOOLTIPS, GENERATE_URLS);
//			
//			        XYPlot plot = chart.getXYPlot();
//			        plot.getRangeAxis().setRange(minY, maxY);
//			
//			        int width = 500;
//			        int height = 300;
//			        ChartUtilities.saveChartAsPNG(
//			            new File(path+algorithm+"_"+yLabel+".png"), chart, width, height);
		        }
	        }
		} catch (FileNotFoundException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
		} finally {
			try {
				if(br!=null)
					br.close();
				if(fr!=null)
					fr.close();
			} catch (IOException e) {
				System.out.println(e);
				e.printStackTrace();
			}
		}
		
		
		try {
			fr = new FileReader(path+"SAT_result.csv");
			if(fr!=null){
				seriesSAT = new XYSeries[18];
				for(int i=0;i<seriesSAT.length;i++)
					seriesSAT[i]=new XYSeries("SAT");
		        br  = new BufferedReader(fr);
		
		        // Get the x-axis label from the first token in the first line
		        // and the y-axis label from the last token in the first line.
		        String line = br.readLine();
		        StringTokenizer st = new StringTokenizer(line, " ");
		        String xLabel = LABEL[0];
		        int i=1;
		         
		        br.close();
		        while(st.hasMoreTokens()){
		        	fr = new FileReader(path+"SAT_result.csv");
		        	br  = new BufferedReader(fr);
		        	 
		        	yLabel = LABEL[i];
			
			        String title = yLabel + " by " + xLabel;
			
			        // Get the data to plot from the remaining lines.
			        float minY = Float.MAX_VALUE;
			        float maxY = -Float.MAX_VALUE;
			        while (true) {
			            line = br.readLine();
			             
			            if (line == null) {
			            	break;
			            }
			            st = new StringTokenizer(line, " ");
			
			            // The first token is the x value.
			            String xValue = st.nextToken();
			
			            // The last token is the y value.
			            String yValue = "";
			            int j=0;
			            while (j<i){
			            	yValue = st.nextToken();
			            	j++;
			            }
			
			            float x = Float.parseFloat(xValue);
			            float y = Float.parseFloat(yValue);
			            seriesSAT[i].add(x, y);
			
			            minY = Math.min(y, minY);
			            maxY = Math.max(y, maxY);
			        }
			        collection[i].addSeries(seriesSAT[i]);
			        i++;
//			        XYSeriesCollection dataset = new XYSeriesCollection();
//			        dataset.addSeries(series);
//			
//			        JFreeChart chart = ChartFactory.createXYLineChart(
//			            title, xLabel, yLabel, dataset,
//			            PlotOrientation.VERTICAL,
//			            SHOW_LEGEND, SHOW_TOOLTIPS, GENERATE_URLS);
//			
//			        XYPlot plot = chart.getXYPlot();
//			        plot.getRangeAxis().setRange(minY, maxY);
//			
//			        int width = 500;
//			        int height = 300;
//			        ChartUtilities.saveChartAsPNG(
//			            new File(path+algorithm+"_"+yLabel+".png"), chart, width, height);
		        }
	        }
		} catch (FileNotFoundException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
		} finally {
			try {
				if(br!=null)
					br.close();
				if(fr!=null)
					fr.close();
			} catch (IOException e) {
				System.out.println(e);
				e.printStackTrace();
			}
		}
		
		
		try {
			fr = new FileReader(path+"OCBR_result.csv");
			if(fr!=null){
				seriesOCBR = new XYSeries[18];
				for(int i=0;i<seriesOCBR.length;i++)
					seriesOCBR[i]=new XYSeries("OCBR");
		        br  = new BufferedReader(fr);
		
		        // Get the x-axis label from the first token in the first line
		        // and the y-axis label from the last token in the first line.
		        String line = br.readLine();
		        StringTokenizer st = new StringTokenizer(line, " ");
		        String xLabel = LABEL[0];
		        int i=1;
		         
		        br.close();
		        while(st.hasMoreTokens()){
		        	fr = new FileReader(path+"OCBR_result.csv");
		        	br  = new BufferedReader(fr);
		        	 
		        	yLabel = LABEL[i];
			
			        String title = yLabel + " by " + xLabel;
			
			        // Get the data to plot from the remaining lines.
			        float minY = Float.MAX_VALUE;
			        float maxY = -Float.MAX_VALUE;
			        while (true) {
			            line = br.readLine();
			             
			            if (line == null) {
			            	break;
			            }
			            st = new StringTokenizer(line, " ");
			
			            // The first token is the x value.
			            String xValue = st.nextToken();
			
			            // The last token is the y value.
			            String yValue = "";
			            int j=0;
			            while (j<i){
			            	yValue = st.nextToken();
			            	j++;
			            }
			
			            float x = Float.parseFloat(xValue);
			            float y = Float.parseFloat(yValue);
			            seriesOCBR[i].add(x, y);
			
			            minY = Math.min(y, minY);
			            maxY = Math.max(y, maxY);
			        }
			        collection[i].addSeries(seriesOCBR[i]);
			        i++;
//			        XYSeriesCollection dataset = new XYSeriesCollection();
//			        dataset.addSeries(series);
//			
//			        JFreeChart chart = ChartFactory.createXYLineChart(
//			            title, xLabel, yLabel, dataset,
//			            PlotOrientation.VERTICAL,
//			            SHOW_LEGEND, SHOW_TOOLTIPS, GENERATE_URLS);
//			
//			        XYPlot plot = chart.getXYPlot();
//			        plot.getRangeAxis().setRange(minY, maxY);
//			
//			        int width = 500;
//			        int height = 300;
//			        ChartUtilities.saveChartAsPNG(
//			            new File(path+algorithm+"_"+yLabel+".png"), chart, width, height);
		        }
	        }
		} catch (FileNotFoundException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
		} finally {
			try {
				if(br!=null)
					br.close();
				if(fr!=null)
					fr.close();
			} catch (IOException e) {
				System.out.println(e);
				e.printStackTrace();
			}
		}
		return collection;
		
		
    }
    
    public JFreeChart[] plot(){
    	final XYDataset[] data=createChart();
    	final XYItemRenderer renderer1 = new StandardXYItemRenderer();
        final XYPlot[] subplot1 = new XYPlot[data.length];
//        final XYPlot sp=new XYPlot(data[1], null, rangeAxis1, renderer1);
//        sp.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
        for(int i=1;i<data.length;i++){
        	subplot1[i]=new XYPlot(data[i], null, new NumberAxis(LABEL[i]), renderer1);
        	subplot1[i].setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
        }
        int width=500;
        int height=400;
        for(int i=1;i<data.length;i++){
        	try {
	        	JFreeChart chart = ChartFactory.createXYLineChart(
		        LABEL[i], LABEL[0], LABEL[i], data[i],
		        PlotOrientation.VERTICAL,
		        SHOW_LEGEND, SHOW_TOOLTIPS, GENERATE_URLS);
	
			    XYPlot plotto = chart.getXYPlot();
		    
				ChartUtilities.saveChartAsPNG(
				new File(path+LABEL[i]+".png"), chart, width, height);
			} catch (IOException e) {
				System.out.println(e);
				e.printStackTrace();
			} catch (Exception e) {
				System.out.println(e);
				e.printStackTrace();
			}
        }
        
        final CombinedDomainXYPlot[] plot = new CombinedDomainXYPlot[data.length-1];
        for(int i=0;i<data.length-1;i++){
        	plot[i]=new CombinedDomainXYPlot();
        	plot[i].setGap(10.0);
        }
        
        // add the subplots...
        for(int i=1;i<data.length;i++){
        	plot[i-1].add(subplot1[i],1);
//        plot.add(sp,1);
        	plot[i-1].setOrientation(PlotOrientation.VERTICAL);
        }
        
        JFreeChart[] chart=new JFreeChart[data.length-1];
        for(int i=0;i<data.length-1;i++){
        	chart[i]=new JFreeChart(LABEL[i+1],
                    JFreeChart.DEFAULT_TITLE_FONT, plot[i], true);
        }
        return chart;
    }
    
    public static void main(String[] args) {
    	ChartCreator plot=new ChartCreator("/home/sunita/results/", "REDS");
		plot.pack();
		RefineryUtilities.centerFrameOnScreen(plot);
		plot.setVisible(true);
    }
}
